#include "Snowflake.h"
#include <QtGlobal>
#include <QThread>
#include <chrono>
#include <QDebug>

Snowflake::Snowflake()
{
    lastTimestamp = 0L;
}

Snowflake::Snowflake(quint64 workerId) : workerId(workerId) {}

quint64 sequence = 0;
quint64 lastTimestamp = 0L;

quint64 Snowflake::generateId()
{
    quint64 timestamp = getCurrentTimestamp();

    if (timestamp < lastTimestamp)
    {
        qDebug() << QString("Clock moved backwards! CurrentTime %1 LastTime %2 .").arg(timestamp).arg(lastTimestamp);
        lastTimestamp = getCurrentTimestamp();
        timestamp = getCurrentTimestamp();
    }

    if (timestamp == lastTimestamp)
    {
        sequence = (sequence + 1) & 0xfff;
        if (sequence == 0)
        {
            timestamp = tilNextMillis(lastTimestamp);
        }
    }
    else
    {
        sequence = 0;
    }

    lastTimestamp = timestamp;

    return ((timestamp - 1288834974657L) << 22) | (workerId << 12) | sequence;
}

quint64 Snowflake::getCurrentTimestamp()
{
    auto now = std::chrono::system_clock::now().time_since_epoch();
    return std::chrono::duration_cast<std::chrono::milliseconds>(now).count();
}

quint64 Snowflake::tilNextMillis(quint64 lastTimestamp)
{
    quint64 timestamp = getCurrentTimestamp();
    while (timestamp <= lastTimestamp)
    {
        timestamp = getCurrentTimestamp();
    }
    return timestamp;
}
